/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.cef.spi.jsonser.util;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.inspur.edp.cef.api.exceptions.ErrorCodes;
import com.inspur.edp.cef.api.manager.ICefValueObjManager;
import com.inspur.edp.cef.api.manager.serialize.CefSerializeContext;
import com.inspur.edp.cef.api.manager.serialize.JsonFormatType;
import com.inspur.edp.cef.api.manager.serialize.NestedSerializeContext;
import com.inspur.edp.cef.api.message.CefException;
import com.inspur.edp.cef.entity.changeset.AbstractModifyChangeDetail;
import com.inspur.edp.cef.entity.changeset.CamelConst;
import com.inspur.edp.cef.entity.changeset.IChangeDetail;
import com.inspur.edp.cef.entity.changeset.ValueObjModifyChangeDetail;
import com.inspur.edp.cef.entity.entity.AssoInfoBase;
import com.inspur.edp.cef.entity.entity.ICefData;
import com.inspur.edp.cef.entity.entity.dynamicProp.IDynamicPropPair;
import com.inspur.edp.cef.entity.entity.dynamicProp.IDynamicPropSet;
import com.inspur.edp.cef.spi.common.UdtManagerUtil;
import com.inspur.edp.cef.spi.entity.AssociationInfo;
import com.inspur.edp.cef.spi.entity.info.propertyinfo.*;
import com.inspur.edp.cef.spi.jsonser.abstractcefchange.BefDateSerUtil;
import com.inspur.edp.cef.spi.jsonser.base.IDynamicPropSerItem;
import com.inspur.edp.cef.spi.jsonser.base.StringUtils;
import com.inspur.edp.udt.entity.IUdtData;
import io.iec.edp.caf.commons.exception.CAFRuntimeException;
import io.iec.edp.caf.commons.exception.ExceptionLevel;
import java.io.IOException;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.*;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class SerializerUtil {

    public SerializerUtil() {
    }

    public static Boolean getBoolean(Object value) {
        if (value == null) {
            return null;
        }
        if (value instanceof Boolean) {
            return Boolean.parseBoolean(value.toString());
        }
        throw new RuntimeException("未识别的值类型：" + value.getClass().getTypeName());
    }

    public static Integer getInteger(Object value) {
        if (value == null) {
            return null;
        }
        if (value instanceof Integer) {
            return Integer.parseInt(value.toString());
        }
        throw new CefException("未识别的值类型：" + value.getClass().getTypeName());
    }

    public static String getString(Object value) {
        if (value == null) {
            return null;
        }
        if (value instanceof String) {
            return value.toString();
        }
        throw new CefException("未识别的值类型：" + value.getClass().getTypeName());
    }

    public static BigDecimal getDecimal(Object value) {
        if (value == null) {
            return null;
        }
        if (value instanceof Double) {
            return BigDecimal.valueOf((Double) value);
        }
        if (value instanceof BigDecimal) {
            return (BigDecimal) value;
        }
        if (value instanceof Long) {
            return BigDecimal.valueOf((Long) value);
        }
        throw new RuntimeException("未识别的值类型：" + value.getClass().getTypeName());
    }

    //TODO 20200307 后面修改
    public static Date getDate(Object value) {
        if (value == null) {
            return null;
        }
        return null;
    }

    public static byte[] getBinary(Object value) {
        if (value == null) {
            return null;
        }
        if (value instanceof byte[]) {
            return (byte[]) value;
        }
        if (value instanceof String) {
            BASE64Decoder decoder = new sun.misc.BASE64Decoder();
            try {
                return decoder.decodeBuffer((String) value);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        throw new RuntimeException("未识别的值类型：" + value.getClass().getTypeName());
    }

    public static boolean isChildCodeEquals(String camel, String normal) {
        Objects.requireNonNull(normal, "normal");
        return normal.equalsIgnoreCase(camel);
    }

    //region Write

    /**
     * 将枚举类型数据写入到Json中
     *
     * @param jsonGenerator      Json写入器
     * @param value              要写入的值
     * @param propertyName       要写入的属性名称
     * @param serializerProvider Json序列化类
     */
    public static void writeEnum(JsonGenerator jsonGenerator, Object value, String propertyName, SerializerProvider serializerProvider) {
        try {
            jsonGenerator.writeFieldName(StringUtils.toCamelCase(propertyName));
            if (value == null) {
                jsonGenerator.writeNull();
            } else {
                jsonGenerator.writeString(String.valueOf(value));
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 将字符类型数据写入到Json中
     *
     * @param jsonGenerator      Json写入器
     * @param value              要写入的值
     * @param propertyName       要写入的属性名称
     * @param serializerProvider Json序列化类
     */
    public static void writeString(JsonGenerator jsonGenerator, Object value, String propertyName, SerializerProvider serializerProvider) {
        try {
            jsonGenerator.writeFieldName(StringUtils.toCamelCase(propertyName));
            if (value == null) {
                jsonGenerator.writeNull();
            } else {
                jsonGenerator.writeString(String.valueOf(value));
            }
        } catch (IOException e) {
            throw new CefException("", "", e, ExceptionLevel.Error);
        }
    }

    /**
     * 将整数类型数据写入到Json中
     *
     * @param jsonGenerator      Json写入器
     * @param value              要写入的值
     * @param propertyName       要写入的属性名称
     * @param serializerProvider Json序列化类
     */
    public static void writeInt(JsonGenerator jsonGenerator, Object value, String propertyName, SerializerProvider serializerProvider) {
        try {
            jsonGenerator.writeFieldName(StringUtils.toCamelCase(propertyName));
            if (value == null) {
                jsonGenerator.writeNull();
            } else {
                jsonGenerator.writeNumber(Integer.parseInt(value.toString()));
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 将小数类型数据写入到Json中
     *
     * @param jsonGenerator      Json写入器
     * @param value              要写入的值
     * @param propertyName       要写入的属性名称
     * @param serializerProvider Json序列化类
     */
    public static void writeDecimal(JsonGenerator jsonGenerator, Object value, String propertyName,
                                      SerializerProvider serializerProvider) {
        writeDecimal(jsonGenerator, value, propertyName, serializerProvider, false);
    }

    public static void writeDecimal(JsonGenerator jsonGenerator, Object value, String propertyName,
                                      SerializerProvider serializerProvider, boolean isBigNumber) {
        if(isBigNumber){
            writeString(jsonGenerator, value, propertyName,serializerProvider);
            return;
        }
        try {
            jsonGenerator.writeFieldName(StringUtils.toCamelCase(propertyName));
            if (value == null) {
                jsonGenerator.writeNull();
            } else {
                jsonGenerator.writeNumber((BigDecimal) value);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 将布尔类型数据写入到Json中
     *
     * @param jsonGenerator      Json写入器
     * @param value              要写入的值
     * @param propertyName       要写入的属性名称
     * @param serializerProvider Json序列化类
     */
    public static void writeBool(JsonGenerator jsonGenerator, Object value, String propertyName, SerializerProvider serializerProvider) {
        try {

            jsonGenerator.writeFieldName(StringUtils.toCamelCase(propertyName));
            if (value == null) {
                jsonGenerator.writeNull();
            } else {
                jsonGenerator.writeBoolean(Boolean.valueOf(value.toString()));
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void writeDateTime(
            JsonGenerator jsonGenerator,
            Object value,
            String propertyName,
            SerializerProvider serializerProvider,
            Boolean enableStdFormat) {
        try {
            jsonGenerator.writeFieldName(StringUtils.toCamelCase(propertyName));
            if (value == null) {
                jsonGenerator.writeNull();
            } else {
                if (enableStdFormat) {
                    jsonGenerator.writeString(BefDateSerUtil.getInstance().writeStdDateTime((Date) value));
                } else {
                    jsonGenerator.writeString(BefDateSerUtil.getInstance().writeDateTime((Date) value));
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void writeStdDateTime(
            JsonGenerator jsonGenerator,
            Object value,
            String propertyName,
            SerializerProvider serializerProvider) {
        writeDateTime(jsonGenerator, value, propertyName, serializerProvider, true);
    }

    public static void writeDate(JsonGenerator jsonGenerator, Object value, String propertyName, SerializerProvider serializerProvider) {
        try {
            jsonGenerator.writeFieldName(StringUtils.toCamelCase(propertyName));
            if (value == null) {
                jsonGenerator.writeNull();
            } else {
                jsonGenerator.writeString(BefDateSerUtil.getInstance().writeDate((Date) value));
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    public  static String getDateProp(Object value){
        if (value == null) {
            return null;
        }
        if (value instanceof Date) {
            return BefDateSerUtil.getInstance().writeDate((Date)value);
        }
        throw new RuntimeException("未识别的值类型：" + value.getClass().getTypeName());
    }

    public  static String getDatetimeProp(Object value){
        if (value == null) {
            return null;
        }
        if (value instanceof Date) {
            return BefDateSerUtil.getInstance().writeDateTime((Date)value);
        }
        throw new RuntimeException("未识别的值类型：" + value.getClass().getTypeName());
    }
    /**
     * 将二进制数组类型数据写入到Json中
     *
     * @param jsonGenerator      Json写入器
     * @param value              要写入的值
     * @param propertyName       要写入的属性名称
     * @param serializerProvider Json序列化类
     */
    public static void writeBytes(JsonGenerator jsonGenerator, Object value, String propertyName,
                                  SerializerProvider serializerProvider) {
        BASE64Encoder encoder = new BASE64Encoder();
        try {
            jsonGenerator.writeFieldName(StringUtils.toCamelCase(propertyName));
            String base64Str = value != null ? encoder.encode((byte[]) value) : "";
            jsonGenerator.writeString(base64Str);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        // Java版临时屏蔽
        // String transValue = Convert.ToBase64String((byte[])((value instanceof byte[])
        // ? value : null));
        // writeBaseType(writer, transValue, propertyName, serializer);
    }

    public static void writeBaseType(JsonGenerator jsonGenerator, Object value, String propertyName,
                                       SerializerProvider serializerProvider) {
        try {
            jsonGenerator.writeFieldName(StringUtils.toCamelCase(propertyName));
            ObjectMapper mapper = new ObjectMapper();
            String valueTemp = mapper.writeValueAsString(value);
            jsonGenerator.writeRawValue(valueTemp);
            // serializerProvider.defaultSerializeValue(value, jsonGenerator);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void writeFieldName(JsonGenerator jsonGenerator, String propertyName) {
        try {
            jsonGenerator.writeFieldName(StringUtils.toCamelCase(propertyName));
        } catch (IOException var4) {
            throw new RuntimeException(var4);
        }
    }

    public static void writeStartObject(JsonGenerator jsonGenerator) {
        try {
            jsonGenerator.writeStartObject();
        } catch (IOException var3) {
            throw new RuntimeException(var3);
        }
    }

    public static void writeEndObject(JsonGenerator jsonGenerator) {
        try {
            jsonGenerator.writeEndObject();
        } catch (IOException var3) {
            throw new RuntimeException(var3);
        }
    }

    public static void writeNestedValue(JsonGenerator jsonGenerator, SerializerProvider serializerProvider, String nestedConfigId, ICefData value, String propertyName, NestedSerializeContext context) {
        ICefValueObjManager val = (ICefValueObjManager) UdtManagerUtil.getUdtFactory().createUdtManager(nestedConfigId);
        val.setNestedSerializeContext(context);
        String str = val.serialize(value);
        try {
            jsonGenerator.writeFieldName(StringUtils.toCamelCase(propertyName));
            jsonGenerator.writeRawValue(str);
        } catch (IOException var10) {
            throw new RuntimeException(var10);
        }
    }

    public static String getNestedValue( String nestedConfigId, ICefData value) {
        ICefValueObjManager val = (ICefValueObjManager) UdtManagerUtil.getUdtFactory().createUdtManager(nestedConfigId);
        String str = val.serialize(value);
        return str;
    }

    public static void writeBasicTypeProp(JsonGenerator writer, Object value) {
        //                throw new RuntimeException("暂不支持类型为" + fieldType.name() + "的属性序列化");
        try {
            if(value == null) {
                writer.writeNull();
                return;
            }
            if (String.class.equals(value.getClass())) {
                writer.writeString(value.toString());
            } else if (Integer.class.equals(value.getClass()) || Float.class.equals(value.getClass()) || Double.class.equals(value.getClass())) {
                writer.writeNumber(value.toString());
            } else if (BigDecimal.class.equals(value.getClass())) {
                writer.writeNumber((BigDecimal)value);
            } else if (Date.class.equals(value.getClass()) || Timestamp.class.equals(value.getClass())||value instanceof Date) {
                writer.writeString(BefDateSerUtil.getInstance().writeDate((Date) value));
                //            case DateTime:
//                SerializerUtil.writeStdDateTime(writer, value, propertyName, serializer);
//                SerializerUtil.writeDateTime(writer, value, propertyName, serializer, serContext.getEnableStdTimeFormat());
            } else if (Boolean.class.equals(value.getClass())) {
                writer.writeBoolean(((Boolean) value).booleanValue());
            } else if (byte[].class.equals(value.getClass())) {
                BASE64Encoder encoder = new BASE64Encoder();
                String base64Str = value != null ? encoder.encode((byte[]) value) : "";
                writer.writeString(base64Str);
            }
            else
                writer.writeNull();
        }
        catch (Exception ex) {
            Exception ex1 = ex;
            ex.printStackTrace();
        }

    }


    public static void writeNestedChange(JsonGenerator jsonGenerator, SerializerProvider serializerProvider, String nestedConfigId, IChangeDetail value, String propertyName) {
        writeNestedChange(jsonGenerator, serializerProvider, nestedConfigId, value, propertyName, (NestedSerializeContext)null);
    }

    public static void writeNestedChange(JsonGenerator jsonGenerator, SerializerProvider serializerProvider, String nestedConfigId, IChangeDetail value, String propertyName, NestedSerializeContext context) {
        ICefValueObjManager val = (ICefValueObjManager)UdtManagerUtil.getUdtFactory().createUdtManager(nestedConfigId);
        val.setNestedSerializeContext(context);
        String str = val.serializeChange(value);

        try {
            jsonGenerator.writeFieldName(StringUtils.toCamelCase(propertyName));
            jsonGenerator.writeRawValue(str);
        } catch (IOException var10) {
            throw new RuntimeException(var10);
        }
    }

    public static void writeDynamicPropSetChange(JsonGenerator writer,
        SerializerProvider serializerProvider, IChangeDetail change, String propertyName,
        IDynamicPropSerItem serItem) {
        Objects.requireNonNull(serItem, "serItem");

        try {
            writer.writeFieldName(StringUtils.toCamelCase(propertyName));
            writer.writeStartObject();

            writer.writeFieldName(CamelConst.ChangeType);
            writer.writeString(CamelConst.ValueObjModifyChangeType);

            writer.writeFieldName(CamelConst.ChangeInfo);
            writer.writeStartObject();

            for (Map.Entry<String, Object> pair : ((AbstractModifyChangeDetail) change)
                .getPropertyChanges().entrySet()) {
                writer.writeFieldName(serItem.getSerializationItemName(pair.getKey()));
                serItem.writeItemChange(pair.getKey(), pair.getValue(), writer, serializerProvider);
            }

            writer.writeEndObject();

            writer.writeEndObject();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void writeDynamicPropSetValue(JsonGenerator writer,
        SerializerProvider serializerProvider,
        IDynamicPropSet data, String propertyName, IDynamicPropSerItem serItem) {
        Objects.requireNonNull(serItem);

        try {
            writer.writeFieldName(StringUtils.toCamelCase(propertyName));
            writer.writeStartObject();
            for (IDynamicPropPair item : data) {
                writer.writeFieldName(serItem.getSerializationItemName(item.getPropName()));
                serItem.writeItemValue(item.getPropName(), item.getPropValue(), writer, serializerProvider);
            }
            writer.writeEndObject();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    //endregion


    public static String getDynamicPropValue(IDynamicPropSet data) {
        StringBuilder returnstring = new StringBuilder();
        returnstring.append("[{");
        try {

            for (IDynamicPropPair item : data) {
                returnstring.append("\""+item.getPropName()+"\":");
                returnstring.append("\""+item.getPropValue()+"\",");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        returnstring.append("}]");
        return returnstring.toString();
    }

    //region Read

    public static String readString(JsonParser p) {
        try {
            return p.getValueAsString();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 读取整型数据
     *
     * @param p 值
     * @return 得到的整数值
     */
    public static int readInt(JsonParser p) {
        try {
            return p.getValueAsInt();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 读取小数数据
     *
     * @param p 值
     * @return 得到的小数值
     */
    public static BigDecimal readDecimal(JsonParser p) {
        try {
            if (JsonToken.VALUE_NULL.equals(p.getCurrentToken())) {
                return null;
            } else if(JsonToken.VALUE_STRING.equals(p.getCurrentToken())){
                Object value = p.getValueAsString();
                return new BigDecimal(value.toString());
//        return p.getDecimalValue();
            }else{
                return p.getDecimalValue();
            }
        } catch (IOException e) {
            throw new RuntimeException("浮点数字解析失败，"+p.toString(), e);
        }
    }

    /**
     * 读取布尔数据
     *
     * @param p 值
     * @return 得到的布尔值
     */
    public static boolean readBool(JsonParser p) {
        try {
            if(p.getCurrentToken() == JsonToken.VALUE_STRING){
                String value = p.getValueAsString();
                if(value.equals("0"))
                    return false;
                return true;
            }
            return p.getValueAsBoolean();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 读取日期数据
     *
     * @param p 值
     * @return 得到的日期值
     */

    public static Date readStdDateTime(JsonParser p) {
        return readDateTime(p, true);
    }

    public static Date readDateTime(JsonParser p, Boolean enableStdDateTime) {
        if (enableStdDateTime) {
            return BefDateSerUtil.getInstance().readStdDateTime(p);
        } else {
            return BefDateSerUtil.getInstance().readDateTime(p);
        }
    }

    public static Date readDateTime(JsonNode node, Boolean enableStdDateTime) {
        if (enableStdDateTime) {
            return BefDateSerUtil.getInstance().readStdDateTime(node);
        } else {
            return BefDateSerUtil.getInstance().readDateTime(node);
        }
    }

    /**
     * 读取二进制数据
     *
     * @param p 值
     * @return 得到的二进制数据值
     */
    public static byte[] readBytes(JsonParser p) {
        if (p == null) {
            return null;
        }
        try {
            return SerializerUtil.getBinary(p.getValueAsString());
        } catch (IOException e) {
            throw new CAFRuntimeException("", ErrorCodes.Scope_ConvertBase64ToBinary, e.getMessage(), e,
                    ExceptionLevel.Error);
        }
    }

    /**
     * 读取枚举数据
     *
     * @param p 值
     * @return 得到的枚举值
     */
    public static <T extends Enum> T readEnum(JsonParser p, Class tClass) {
        if(JsonToken.VALUE_NULL.equals(p.getCurrentToken())){
            return null;
        }

        try {
            if(p.getValueAsString().equals(""))
                return null;
            return (T) Enum.valueOf(tClass, p.getValueAsString());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static <T extends Enum> T readEnum(JsonNode node, Class tClass) {

        if(node.isNull()){
            return null;
        }

        String value = node.textValue();
        if(StringUtils.isNullOrEmpty(value))
            return null;
        return (T) Enum.valueOf(tClass, value);
    }

    public static  <T> T readNestedValue(String nestedConfigId, JsonParser p,
                                          DeserializationContext ctxt) {
        return readNestedValue(nestedConfigId, p, ctxt, null);
    }

    public static <T> T readNestedValue(String nestedConfigId, JsonParser p,
                                          DeserializationContext ctxt,
                                          NestedSerializeContext nestedSerializeContext) {
        ICefValueObjManager val = (ICefValueObjManager) UdtManagerUtil.getUdtFactory()
                .createUdtManager(nestedConfigId);
        val.setNestedSerializeContext(nestedSerializeContext);
        try {
            return (T) val.deserialize(p.readValueAsTree().toString());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static <T> T readNestedValue(String nestedConfigId,
                                        HashMap<String, JsonNode> nodes,
                                        ICefData data,
                                        NestedSerializeContext nestedSerializeContext) {
        ICefValueObjManager val = (ICefValueObjManager) UdtManagerUtil.getUdtFactory()
                .createUdtManager(nestedConfigId);
        val.setNestedSerializeContext(nestedSerializeContext);
        return (T) val.deserialize(nodes, data);
    }

    public static IChangeDetail readNestedChange(String nestedConfigId, JsonParser p, DeserializationContext ctxt) {
        try {
            return readNestedChange(nestedConfigId, (JsonNode)p.readValueAsTree(), ctxt);
        } catch (IOException var5) {
            throw new RuntimeException(var5);
        }
    }

    public static IChangeDetail readNestedChange(String nestedConfigId, JsonNode value, DeserializationContext ctxt) {
        return readNestedChange(nestedConfigId, (JsonNode)value, ctxt, (NestedSerializeContext)null);
    }


    public static IChangeDetail readNestedChange(String nestedConfigId, JsonParser p, DeserializationContext ctxt, NestedSerializeContext nestedSerializeContext) {
        try {
            return readNestedChange(nestedConfigId, (JsonNode)p.readValueAsTree(), ctxt, nestedSerializeContext);
        } catch (IOException var5) {
            throw new RuntimeException(var5);
        }
    }

    public static IChangeDetail readNestedChange(String nestedConfigId, JsonNode value, DeserializationContext ctxt, NestedSerializeContext nestedSerializeContext) {
        Object tempVar = UdtManagerUtil.getUdtFactory().createUdtManager(nestedConfigId);
        ICefValueObjManager val = (ICefValueObjManager)((ICefValueObjManager)(tempVar instanceof ICefValueObjManager ? tempVar : null));
        val.setNestedSerializeContext(nestedSerializeContext);
        return val.deserializeChange(value.toString());
    }

    public static IChangeDetail readNestedChange(String nestedConfigId,
                                        HashMap<String, JsonNode> nodes,
                                        IChangeDetail changeDetail,
                                        NestedSerializeContext nestedSerializeContext) {
        ICefValueObjManager val = (ICefValueObjManager) UdtManagerUtil.getUdtFactory()
                .createUdtManager(nestedConfigId);
        val.setNestedSerializeContext(nestedSerializeContext);
        return val.deserializeChange(nodes, changeDetail);
    }

    public static IUdtData createUdt(String nestedConfigId) {
        Object tempVar = UdtManagerUtil.getUdtFactory().createManager(nestedConfigId);
        ICefValueObjManager val = (ICefValueObjManager)((ICefValueObjManager)(tempVar instanceof ICefValueObjManager ? tempVar : null));

        return (IUdtData) val.createDataType();
//        val.setNestedSerializeContext(nestedSerializeContext);
//        return val.deserializeChange(value.toString());
    }

    public static void readDynamicPropSetValue(IDynamicPropSet data, String dynPropSetPropName,
        IDynamicPropSerItem serItem,
        JsonParser reader, DeserializationContext ctx) {
        Objects.requireNonNull(serItem);

        try {
            reader.nextToken();
            while (reader.getCurrentToken() != JsonToken.END_OBJECT) {
                String propName = serItem.getActualItemName((String) reader.getValueAsString());
                reader.nextToken();
                data.setValue(propName, serItem.readItemValue(propName, reader, ctx));
                reader.nextToken();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static IChangeDetail readDynamicPropSetChange(JsonParser reader, DeserializationContext ctx,
        String dynPropSetPropName, IDynamicPropSerItem serItem) {
        Objects.requireNonNull(serItem);
        JsonParser objReader = null;
        try {
            objReader = reader.readValueAsTree().traverse(new ObjectMapper());
            objReader.nextToken();
            while (!CamelConst.ChangeInfo.equalsIgnoreCase(objReader.getValueAsString())) {
                objReader.nextToken();
            }
            ValueObjModifyChangeDetail changeDetail = new ValueObjModifyChangeDetail();

            objReader.nextToken();
            objReader.nextToken();

            while (objReader.getCurrentToken() == JsonToken.FIELD_NAME) {
                String propName = serItem.getActualItemName((String) objReader.getValueAsString());
                objReader.nextToken();
                changeDetail.getPropertyChanges()
                    .put(propName, serItem.readItemChange(propName, objReader, ctx));
                objReader.nextToken();
            }
            return changeDetail;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    //endregion

    private static ThreadLocal<String> keepAssoPropertyForExpression = new ThreadLocal<>();
    public static ThreadLocal<String> isKeepAssoPropertyForExpression()
    {return keepAssoPropertyForExpression;}
}
